﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using Struct = System.Int32;

namespace ArgusPCLib.Mathematics.StructWrappers
{
	public struct Int32Wrapper : ILinearScalar
	{
		Struct _value;

		public Int32Wrapper(Struct value)
		{
			this._value = value;
		}

		public static implicit operator Int32Wrapper(Struct value)
		{
			return new Int32Wrapper(value);
		}

		public static implicit operator Struct(Int32Wrapper value)
		{
			return value._value;
		}

		public override string ToString()
		{
			return this.ToString(null, null);
		}

		#region IOperand
		public static Int32Wrapper Parse(string text, string format, IFormatProvider formatProvider)
		{
			NumberStyles numberStyle;
			if (format != null && format.ToLowerInvariant().StartsWith("h"))
				numberStyle = NumberStyles.HexNumber;
			else
				numberStyle = NumberStyles.Integer;
			return Struct.Parse(text, numberStyle, formatProvider);
		}

		public static bool TryParse(string text, string format, IFormatProvider formatProvider, out Int32Wrapper value)
		{
			NumberStyles numberStyle;
			if (format != null && format.ToLowerInvariant().StartsWith("h"))
				numberStyle = NumberStyles.HexNumber;
			else
				numberStyle = NumberStyles.Integer;

			Struct result;
			if (Struct.TryParse(text, numberStyle, formatProvider, out result))
			{
				value = new Int32Wrapper(result);
				return true;
			}
			else
			{
				value = new Int32Wrapper();
				return false;
			}
		}

		public static int PartialParse(string text, string format, IFormatProvider formatProvider, out Int32Wrapper value)
		{
			int start;
			for (start = 0; start < text.Length; start++)
			{
				if (!char.IsWhiteSpace(text[start]))
					break;
			}

			NumberFormatInfo nfi = (NumberFormatInfo)formatProvider;

			NumberStyles numberStyle;
			if (format != null && format.ToLowerInvariant().StartsWith("h"))
				numberStyle = NumberStyles.HexNumber;
			else
				numberStyle = NumberStyles.Integer;

			int start2 = start;
			if (text.Substring(start, nfi.NegativeSign.Length) == nfi.NegativeSign)
				start2 = start + nfi.NegativeSign.Length;
			else if (text.Substring(start, nfi.PositiveSign.Length) == nfi.PositiveSign)
				start2 = start + nfi.PositiveSign.Length;

			int end;
			for (end = start2; end < text.Length; end++)
			{
				if (char.IsNumber(text[end]))
					continue;
				if (numberStyle == NumberStyles.HexNumber)
				{
					char c = char.ToLowerInvariant(text[end]);
					if (c >= 'a' && c <= 'f')
						continue;
				}
				break;
			}

			if (end - start < 1)
			{
				value = new Int32Wrapper();
				return -1;
			}

			value = new Int32Wrapper(int.Parse(text.Substring(start, end - start), numberStyle, formatProvider));
			return end;
		}

		IOperand IOperand.GetDeepCopy() { return new Int32Wrapper(this._value); }
		#endregion

		#region IFormattable
		public string ToString(string format, IFormatProvider formatProvider)
		{
			return this._value.ToString(format, formatProvider);
		}
		#endregion

		#region IScalar
		public static Int32Wrapper Zero { get { return new Int32Wrapper(0); } }
		public static Int32Wrapper One { get { return new Int32Wrapper(1); } }

		public static Int32Wrapper operator +(Int32Wrapper a, Int32Wrapper b)
		{
			return new Int32Wrapper(a._value + b._value);
		}

		public static Int32Wrapper operator -(Int32Wrapper a, Int32Wrapper b)
		{
			return new Int32Wrapper(a._value - b._value);
		}

		public static Int32Wrapper operator *(Int32Wrapper a, Int32Wrapper b)
		{
			return new Int32Wrapper(a._value * b._value);
		}

		public static Int32Wrapper operator /(Int32Wrapper a, Int32Wrapper b)
		{
			return new Int32Wrapper(a._value / b._value);
		}

		public static bool operator ==(Int32Wrapper a, Int32Wrapper b)
		{
			return a._value == b._value;
		}

		public static bool operator !=(Int32Wrapper a, Int32Wrapper b)
		{
			return a._value != b._value;
		}

		IScalar IScalar.Add(IScalar value) { return this + (Int32Wrapper)value; }
		IScalar IScalar.Multiply(IScalar value) { return this * (Int32Wrapper)value; }
		IScalar IScalar.Subtract(IScalar value) { return this - (Int32Wrapper)value; }
		IScalar IScalar.Divide(IScalar value) { return this / (Int32Wrapper)value; }
		bool IScalar.IsEqualTo(IScalar value) { return this == (Int32Wrapper)value; }
		#endregion

		#region ILinearScalar
		public static bool operator <(Int32Wrapper a, Int32Wrapper b)
		{
			return a._value < b._value;
		}

		public static bool operator >(Int32Wrapper a, Int32Wrapper b)
		{
			return a._value > b._value;
		}

		public static bool operator <=(Int32Wrapper a, Int32Wrapper b)
		{
			return a._value <= b._value;
		}

		public static bool operator >=(Int32Wrapper a, Int32Wrapper b)
		{
			return a._value >= b._value;
		}

		bool ILinearScalar.IsGreaterThan(ILinearScalar value) { return this > (Int32Wrapper)value; }
		bool ILinearScalar.IsSmallerThan(ILinearScalar value) { return this < (Int32Wrapper)value; }
		#endregion

		#region IComparable
		int IComparable.CompareTo(object obj)
		{
			Int32Wrapper b = (Int32Wrapper)obj;
			if (this._value < b._value)
				return -1;
			if (this._value > b._value)
				return 1;
			return 0;
		}
		#endregion
	}
}
